package server.main;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

import server.map.Gate;
import server.map.Map;
import server.map.MapsDefinition;
import server.map.Platform;
import server.map.Stair;
import server.mobiles.MobMoves;
import server.mobiles.Mobile;
import server.mobiles.PlayerMobile;
import server.utility.Id;
import server.utility.Point2d;


public class Data {
	public static final Id internal = new Id(-1);
	public static final Id bornMap=new Id(11);
	private static HashMap<Id,Mobile> mobs;
	private static HashMap<String, Id> users;
	private static Timer mobMoveTimer;
	private static HashMap<Id, Map> maps;
	private static Timer saveTimer;
	private final static String savePath = "saves"+File.separator;
	
	static{
		/*users=new HashMap<String, Id>();
		maps=new HashMap<Id, Map>();
		mobs=new HashMap<Id,Mobile>();
		
		//to test
		PlayerMobile pm=PlayerMobile.create("dio");
		PlayerMobile pm1=PlayerMobile.create("dio1");
		PlayerMobile pm2=PlayerMobile.create("dio2");
		
		
		
		bornMap.spawn(new Point2d(200,200), new Mobile("brutto"));
		bornMap.spawn(new Point2d(300,100), new Mobile("brutto1"));
		//end
		
		mobMoveTimer=new Timer("mob move timer", false);
		mobMoveTimer.scheduleAtFixedRate(new MobMoves(mobs.values()), 1000, 1000);
		try {
			save();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
		
		try {
			load();
			
			for(Id id:users.values()){
				Mobile m=mobs.get(id);
				
				if(m.isPlayer())
					((PlayerMobile)m).logout();
			}
			
			mobMoveTimer=new Timer("mob move timer", false);
			mobMoveTimer.scheduleAtFixedRate(new MobMoves(mobs.values()), 1000, 1000);
			
			saveTimer = new Timer("world saving timer", false);
			saveTimer.scheduleAtFixedRate(new SaveTask(), 60000, 60000);
		}
		catch (Exception e) {e.printStackTrace();}
		
		
	}
	
	private static class SaveTask extends TimerTask{
		@Override
		public void run() {
			try {Data.save();}
			catch (IOException e) {e.printStackTrace();}
		}
	}
	
	public static void add(Mobile m){
		mobs.put(m.getId(),m);
	}

	public static void remove(Mobile m) {
		mobs.remove(m);
	}
	
	public static void add(PlayerMobile m){
		users.put(m.getName(), m.getId());
		add((Mobile)m);
	}
	
	public static void add(Map m){
		maps.put(m.getId(), m);
	}
	
	public static PlayerMobile getUser(String name){
		try{return (PlayerMobile) mobs.get(users.get(name.trim()));
		}catch(Exception ex){return null;}
	}

	public static String getMobPositions(String line) {
		String res="";
		
		Id playerid=new Id(Integer.parseInt(line));
		Mobile pl=mobs.get(playerid);
		
		pl.update();
		
		res+=pl.getMap().toString()+";";
		
		for(Mobile mob:pl.getVisibleMobile()){
			//if(mob!=pl)
			res+=mob.getId()+"@"+mob.getPosition()+","+mob.getHealth()+","+mob.getMaxHealth()+";";
		}
		
		res+="\n";
		
		return res;
	}

	public static boolean hasUser(String name) {
		return users.containsKey(name);
	}
	
	private static void load() throws IOException, ClassNotFoundException{
		if(!(new File("mobs.save").exists())){
			
			
			mobs=new HashMap<Id, Mobile>();
			users=new HashMap<String, Id>();
			maps=new HashMap<Id, Map>();
			
			MapsDefinition.loadMaps();
			
			return;
		}
		
		
		System.out.println("Loading...");
		FileInputStream fis = new FileInputStream(savePath + "mobs.save");
		ObjectInputStream iis = new ObjectInputStream(fis);
		mobs = (HashMap<Id, Mobile>)iis.readObject();
		iis.close();
		
		fis = new FileInputStream(savePath + "user.save");
		iis = new ObjectInputStream(fis);
		users = (HashMap<String, Id>) iis.readObject();
		iis.close();
		
		//fis = new FileInputStream(savePath + "maps.save");
		//iis = new ObjectInputStream(fis);
		//maps = (HashMap<Id, Map>) iis.readObject();
		//iis.close();
		
		MapsDefinition.loadMaps();
		
		System.out.println("done!");
	}
	
	public static void save() throws IOException{
		File dir = new File(savePath);
		
	    if (!dir.exists()) {
	    	dir.mkdir();
	    }
		System.out.println("saving mobs...");
		FileOutputStream fos = new FileOutputStream(savePath + "mobs.save");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(mobs);
		oos.close();
		
		System.out.println("saving users...");
		fos = new FileOutputStream(savePath + "user.save");
		oos = new ObjectOutputStream(fos);
		oos.writeObject(users);
		oos.close();
		
		System.out.println("saving maps...");
		//fos = new FileOutputStream(savePath + "maps.save");
		//oos = new ObjectOutputStream(fos);
		//oos.writeObject(maps);
		//oos.close();
		System.out.println("saving done");
	}

	public static Map getMap(Id id) {
		return maps.get(id);
	}

	public static Mobile getMobile(String s) {
		Id id=new Id(Integer.parseInt(s));
		
		return mobs.get(id);
	}

}